#ifndef _DEBUG_H
#define _DEBUG_H

#include <wx/string.h>

#ifndef NDEBUG
#include <map>
#include <set>
#include <typeinfo>
#endif

extern int log_nest_level;

#define MAX_ERROR_MESSAGE_LENGTH 2048

void lognest();
void init_log(const char* filename);
void close_log();

// dbg() macro
void do_log(const wxString& msg);
#define dbg(format, ...) do_log(wxString::Format(format, ## __VA_ARGS__))

// dbgenter() macro add one indent to log, until the end of current scope
#define dbgenter(format, ...) dbg(format, ## __VA_ARGS__); volatile LogNestProxy lognestproxy;
class LogNestProxy{
public:
    LogNestProxy() {log_nest_level++;}
    ~LogNestProxy() {log_nest_level--;}
};

#ifdef NDEBUG
template <class T>
class InstanceWatcher {};
inline void InstanceWatcherCheck() {}
#else
extern std::map<const char *, std::set<void*> > inst;
void InstanceWatcherCheck();

template <class T>
class InstanceWatcher
{
public:
    InstanceWatcher(const InstanceWatcher&) {
        inst[typeid(T).name()].insert(this);
    }
    InstanceWatcher() {
        inst[typeid(T).name()].insert(this);
    }
    ~InstanceWatcher() {
        if (inst[typeid(T).name()].count(this))
            inst[typeid(T).name()].erase(this);
    }
};
#endif

#endif
